#include "i2c_app.h"




#include "driver_gpio.h"
#include "driver_i2c.h"
#include "hardware_iic.h"


#define MASTER    1


static GPIO_InitTypeDef   GPIO_Handle;
static I2C_HandleTypeDef  I2C0_Handle;

static uint8_t data[2]={0};
static uint8_t i2c_slave_RxBufferI2C[256]={0};



uint8_t TxBufferI2C[256];
uint8_t RxBufferI2C[256];

static uint32_t recv_count = 0;
static uint32_t send_count = 0;



void user_i2c_app_init(void)
{
	  __SYSTEM_GPIO_CLK_ENABLE();
		__SYSTEM_I2C0_CLK_ENABLE();
	
	  /* I2C IO Init */
    GPIO_Handle.Pin       = GPIO_PIN_0 | GPIO_PIN_1;
    GPIO_Handle.Mode      = GPIO_MODE_AF_PP;
    GPIO_Handle.Pull      = GPIO_PULLUP;
    GPIO_Handle.Alternate = GPIO_FUNCTION_1;
    gpio_init(GPIO_D, &GPIO_Handle);
		

    I2C0_Handle.I2Cx = I2C0;
	  #if MASTER
    I2C0_Handle.Init.I2C_Mode = I2C_MODE_MASTER_7BIT;
	  printf("MASTER Init\r\n");
		#else
		printf("SLAVE Init\r\n");
	  I2C0_Handle.Init.I2C_Mode = I2C_MODE_SLAVE_7BIT;
	  I2C0_Handle.Init.Slave_Address = 0xA7;
		#endif
    I2C0_Handle.Init.SCL_HCNT = 50;
    I2C0_Handle.Init.SCL_LCNT = 50;
    i2c_init(&I2C0_Handle);
		
		
		#if  !MASTER
		i2c_int_enable(&I2C0_Handle, INT_RX_FULL|INT_RD_REQ);
    NVIC_EnableIRQ(I2C0_IRQn);
    co_delay_100us(1000);
    __I2C_ENABLE(I2C0_Handle.I2Cx);
		#endif
	
	#if  MASTER
	while(1)
	{
		
		#if 1
	  i2c_master_Write(0xA7,0x45,0x67);
		#else
    i2c_master_Read(0xA7,0x37,data,1);
		printf("data=%d\r\n",data[0]);
		#endif
		
	}
	#else
	
	while(1)
	{
	
	  //printf("data=%d\r\n",data[0]);
	}
	
	
	#endif
	


}



uint8_t i2c_master_Write(uint8_t slave_address,uint8_t cmd_reg,uint8_t data)
{
	uint8_t buff[2];
	buff[0] = cmd_reg;
	buff[1] = data;
	i2c_master_transmit(&I2C0_Handle,slave_address,buff,2);
	return 	true;
}
uint8_t i2c_master_Read(uint8_t slave_address,uint8_t cmd_reg,uint8_t *data,uint8_t len)
{
	i2c_master_transmit(&I2C0_Handle,slave_address,&cmd_reg,1);
	i2c_master_receive(&I2C0_Handle,slave_address,data,len);
	
	return 	true;
}




__attribute__((section("ram_code"))) void i2c_isr0(void)
{
	
	printf("%s\r\n",__FUNCTION__);
//    LOG_INFO(NULL, "i2c0_isr: %04x\r\n", I2C0_Handle.I2Cx->RAW_INT_STAT);
    
    if(i2c_get_int_status(&I2C0_Handle, INT_RD_REQ)) {
        if(i2c_get_int_status(&I2C0_Handle, INT_TX_ABRT)) {
            i2c_clear_int_status(&I2C0_Handle, INT_TX_ABRT);
        }
        I2C0_Handle.I2Cx->DATA_CMD = i2c_slave_RxBufferI2C[send_count++];
        i2c_clear_int_status(&I2C0_Handle, INT_RD_REQ);
    }
    
//    if(i2c_get_int_status(&I2C0_Handle, INT_ACTIVITY)) {
//        i2c_clear_int_status(&I2C0_Handle, INT_ACTIVITY);
//    }
//    
//    if(i2c_get_int_status(&I2C0_Handle, INT_STOP_DET)) {
//        i2c_clear_int_status(&I2C0_Handle, INT_STOP_DET);
//    }
//    
//    if(i2c_get_int_status(&I2C0_Handle, INT_START_DET)) {
//        i2c_clear_int_status(&I2C0_Handle, INT_START_DET);
//    }
    
    if(i2c_get_int_status(&I2C0_Handle, INT_RX_FULL)) {
        i2c_clear_int_status(&I2C0_Handle, INT_RX_FULL);
        
        while (!__I2C_IS_RxFIFO_EMPTY(I2C0_Handle.I2Cx)) 
        {
            volatile uint8_t data = I2C0_Handle.I2Cx->DATA_CMD & 0xFF;
            i2c_slave_RxBufferI2C[(recv_count++)%255] = data;            

            printf("i2c_demo: I2C0 receive: %02x.\r\n", data);
        }
    }
}